package org.example.oauth2.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * 首先我们来定义一个专门的类 TokenTask 用来解决 Token 的管理问题
 */
@Component
public class TokenTask {

    @Autowired
    RestTemplate restTemplate;

    private String access_token;
    private String refresh_token;

    /**
     * 首先在 getData 方法中，如果 access_token 为空字符串，并且 code 不为 null，
     * 表示这是刚刚拿到授权码的时候，准备去申请令牌了，令牌拿到之后，将 access_token 和 refresh_token 分别赋值给变量，
     * 然后调用 loadDataFromResServer 方法去资源服务器加载数据。
     */
    public String getData(String code) {
        if (!StringUtils.hasText(access_token) && StringUtils.hasText(code)) {
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("code", code);
            map.add("client_id", "clientId_1");
            map.add("client_secret", "secret_1");
            map.add("redirect_uri", "http://localhost:8083/index.html");
            map.add("grant_type", "authorization_code");
            Map<String, String> resp = restTemplate.postForObject("http://localhost:8081/oauth/token", map, Map.class);
            System.out.println(resp);
            access_token = resp.get("access_token");
            refresh_token = resp.get("refresh_token");
        }
        return loadDataFromResServer();
    }

    private String loadDataFromResServer() {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Bearer " + access_token);
            HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
            ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8082/admin/hello", HttpMethod.GET, httpEntity, String.class);
            return entity.getBody();
        } catch (RestClientException e) {
            return "未加载";
        }
    }

    /**
     * 另外有一个 tokenTask 方法，这是一个定时任务，每隔 115 分钟去刷新一下 access_token（access_token 有效期是 120 分钟）
     */
    @Scheduled(fixedDelay = (1000 * 60 * 115))
    public void tokenTask() {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("client_id", "clientId_1");
        map.add("client_secret", "secret_1");
        map.add("refresh_token", refresh_token);
        map.add("grant_type", "refresh_token");
        Map<String, String> resp = restTemplate.postForObject("http://localhost:8081/oauth/token", map, Map.class);
        System.out.println(resp);
        access_token = resp.get("access_token");
        refresh_token = resp.get("refresh_token");
    }

}
